global loader_switchto

%define task_sizeof	20
%define task_cr3	12
%define task_esp	16
%define max_pid		32

%macro task_table_pos 1
	mov eax, dword task_sizeof
	mul %1
	mov edx, task_table
	add edx, eax
%endmacro

extern loader_cleanup
extern current_pid
extern task_table
extern remove_last

loader_switchto:
	push ebp
	mov ebp, esp
	push ebx
	xor ecx, ecx
	mov ebx, dword [current_pid]; tarea actual
	mov ecx, dword [ebp + 8]    ; tarea a la que voy a cambiar
	cmp ecx, ebx
	je .loader_switchto_ret ; si las dos tareas son la misma salgo
	;cambio current_pid
	mov dword [current_pid], ecx
	;si es la primera tarea que cargo, NO tengo que guardar el ESP de la tarea anterior...
	cmp ebx, max_pid
	je .loader_switchto_load
	;obtengo task_table[pid_tarea_vieja]
	task_table_pos ebx
	;guardo esp
	mov [edx + task_esp], esp
.loader_switchto_load:
	;xchg bx,bx
	; obtengo task_table[pid_tarea_nueva]
	task_table_pos ecx
	xor eax, eax
	; seteo pila y cr3 de la tarea nueva
	mov eax, [edx + task_cr3]
	mov ecx, [edx + task_esp]
	mov cr3, eax
	mov esp, ecx
	; veo si tengo que destruir la tarea anterior
	cmp dword [remove_last], dword 0
	je .loader_switchto_ret
	push ebx
	call loader_cleanup
	add esp, 4
.loader_switchto_ret:
	pop ebx
	pop ebp
	;xchg bx, bx
	ret
